package com.benio.ycfdisplayer.fresco;

import android.net.Uri;
import android.text.TextUtils;

import com.benio.ycfdisplayer.displayer.DisplayListener;
import com.benio.ycfdisplayer.displayer.Options;
import com.benio.ycfdisplayer.displayer.Target;
import com.facebook.common.internal.Preconditions;
import com.facebook.drawee.backends.pipeline.Fresco;
import com.facebook.drawee.backends.pipeline.PipelineDraweeControllerBuilder;
import com.facebook.drawee.controller.BaseControllerListener;
import com.facebook.drawee.generic.GenericDraweeHierarchy;
import com.facebook.drawee.interfaces.DraweeController;
import com.facebook.drawee.interfaces.DraweeHierarchy;
import com.facebook.imagepipeline.image.ImageInfo;
import com.facebook.imagepipeline.request.ImageRequest;
import com.facebook.imagepipeline.request.ImageRequestBuilder;

/**
 * 将Options中的配置加载到Fresco中
 * Created by zhangzhibin on 2016/9/30.
 */
public class FrescoOptionsApplier {

    public static ImageRequest newImageRequest(Uri uri, Options o) {
        if (uri == null || o == null || !(o instanceof FrescoDisplayOptions)) {
            return ImageRequest.fromUri(uri);
        }

        FrescoDisplayOptions options = (FrescoDisplayOptions) o;
        ImageRequestBuilder builder = ImageRequestBuilder
                .newBuilderWithSource(uri)
                .setAutoRotateEnabled(options.autoRotateEnabled)
                .setLocalThumbnailPreviewsEnabled(options.localThumbnailPreviewsEnabled)
                .setProgressiveRenderingEnabled(options.progressiveRenderingEnabled);
        if (options.lowestPermittedRequestLevel != null) {
            builder.setLowestPermittedRequestLevel(options.lowestPermittedRequestLevel);
        }
        if (options.imageDecodeOptions != null) {
            builder.setImageDecodeOptions(options.imageDecodeOptions);
        }
        if (options.resizeOptions != null) {
            builder.setResizeOptions(options.resizeOptions);
        }
        if (options.requestPriority != null) {
            builder.setRequestPriority(options.requestPriority);
        }
        if (options.postprocessor != null) {
            builder.setPostprocessor(options.postprocessor);
        }
        if (options.cacheChoice != null) {
            builder.setCacheChoice(options.cacheChoice);
        }
        if (!options.diskCacheEnabled) {
            builder.disableDiskCache();
        }
        return builder.build();
    }

    /**
     * 将加载配置设置到GenericDraweeHierarchy中
     */
    private static DraweeHierarchy applyOptionsToHierarchy(Options o, DraweeHierarchy h) {
        if (h == null || o == null || !(h instanceof GenericDraweeHierarchy)) {
            return h;
        }
        GenericDraweeHierarchy hierarchy = (GenericDraweeHierarchy) h;

        if (!(o instanceof FrescoDisplayOptions)) {
            if (o.failureImage != null) {
                hierarchy.setFailureImage(o.failureImage);
            }
            if (o.placeHolderImage != null) {
                hierarchy.setPlaceholderImage(o.placeHolderImage);
            }
            return h;
        }

        FrescoDisplayOptions options = (FrescoDisplayOptions) o;
        if (options.failureImage != null) {
            hierarchy.setFailureImage(options.failureImage, options.failureImageScaleType);
        }
        if (options.placeHolderImage != null) {
            hierarchy.setPlaceholderImage(options.placeHolderImage, options.placeholderImageScaleType);
        }
        if (options.retryImage != null) {
            hierarchy.setRetryImage(options.retryImage, options.retryImageScaleType);
        }
        if (options.progressBarImage != null) {
            hierarchy.setProgressBarImage(options.progressBarImage, options.progressBarImageScaleType);
        }
        if (options.backgroundImage != null) {
            hierarchy.setBackgroundImage(options.backgroundImage);
        }
        if (options.actualImageFocusPoint != null) {
            hierarchy.setActualImageFocusPoint(options.actualImageFocusPoint);
        }
        if (options.actualImageColorFilter != null) {
            hierarchy.setActualImageColorFilter(options.actualImageColorFilter);
        }
        if (options.roundingParams != null) {
            hierarchy.setRoundingParams(options.roundingParams);
        }
        hierarchy.setFadeDuration(options.fadeDuration);
        hierarchy.setActualImageScaleType(options.actualImageScaleType);
        return hierarchy;
    }

    private static PipelineDraweeControllerBuilder newControllerBuilder(Options o) {
        PipelineDraweeControllerBuilder builder = Fresco.newDraweeControllerBuilder();
        if (o != null && o instanceof FrescoDisplayOptions) {
            FrescoDisplayOptions options = (FrescoDisplayOptions) o;
            builder.setTapToRetryEnabled(options.tapToRetryEnabled)
                    .setAutoPlayAnimations(options.autoPlayAnimations)
                    .setRetainImageOnFailure(options.retainImageOnFailure);
        }
        return builder;
    }

    public static <T extends Target & FrescoView> PipelineDraweeControllerBuilder newControllerBuilder(Uri uri, T target, Options options, DisplayListener listener) {
        Preconditions.checkNotNull(target);
        final DraweeHierarchy hierarchy = target.getHierarchy();
        final DraweeController controller = target.getController();
        applyOptionsToHierarchy(options, hierarchy);

        BaseControllerListener<ImageInfo> listenerWrapper = null;
        if (listener != null) {
            listenerWrapper = new ControllerListenerWrapper(uri == null ? null : uri.toString(), target.getView(), listener);
        }
        return newControllerBuilder(options)
                .setImageRequest(newImageRequest(uri, options))
                .setControllerListener(listenerWrapper)
                .setOldController(controller);
    }

    public static <T extends Target & FrescoView> PipelineDraweeControllerBuilder newControllerBuilder(String uri, T target, Options options, DisplayListener listener) {
        return newControllerBuilder(TextUtils.isEmpty(uri) ? null : Uri.parse(uri), target, options, listener);
    }

}
